package com.eastrobot.report.db;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.pool.DruidDataSource;
import com.eastrobot.report.util.PropUtil;

/**
 * 连接数据库
 * 
 * @author baoy
 * 
 */
public class DBconnection {
	
	private  final Logger logger = LoggerFactory.getLogger(DBconnection.class);
	private static DBconnection db = new DBconnection();
	public Map<String, String> jdbcProp;
	
	private DBconnection() {
		jdbcProp = PropUtil.loadPropsToMap("jdbc.properties");
		dataSource = new DruidDataSource();
		dataSource.setUrl(jdbcProp.get("jdbc.url"));
		dataSource.setDriverClassName(jdbcProp.get("jdbc.driverClass"));
		dataSource.setUsername(jdbcProp.get("jdbc.username"));
		dataSource.setPassword(jdbcProp.get("jdbc.password"));
		dataSource.setInitialSize(initialSize);
		dataSource.setMinIdle(minIdle);
		dataSource.setMaxActive(maxActive);
		dataSource.setMaxWait(maxWait);
		dataSource.setTimeBetweenConnectErrorMillis(timeBetweenConnectErrorMillis);
		dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
		dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);

		dataSource.setValidationQuery(validationQuery);
		dataSource.setTestWhileIdle(testWhileIdle);
		dataSource.setTestOnBorrow(testOnBorrow);
		dataSource.setTestOnReturn(testOnReturn);

		dataSource.setRemoveAbandoned(removeAbandoned);
		dataSource.setRemoveAbandonedTimeoutMillis(removeAbandonedTimeoutMillis);
		dataSource.setLogAbandoned(logAbandoned);
		dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
	}

	public static DBconnection getInstance() { return db; }
	

	private  DruidDataSource dataSource;
	private  Connection conn = null;
	// 初始连接池大小、最小空闲连接数、最大活跃连接数
	private  int initialSize = 10;
	private  int minIdle = 10;
	private  int maxActive = 100;

	// 配置获取连接等待超时的时间
	private  long maxWait = DruidDataSource.DEFAULT_MAX_WAIT;

	// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
	private  long timeBetweenEvictionRunsMillis = DruidDataSource.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
	// 配置连接在池中最小生存的时间
	private  long minEvictableIdleTimeMillis = DruidDataSource.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
	// 配置发生错误时多久重连
	private  long timeBetweenConnectErrorMillis = DruidDataSource.DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS;

	private  String validationQuery = "select 1";
	private  boolean testWhileIdle = true;
	private  boolean testOnBorrow = false;
	private  boolean testOnReturn = false;

	// 是否打开连接泄露自动检测
	private  boolean removeAbandoned = false;
	// 连接长时间没有使用，被认为发生泄露时长
	private  long removeAbandonedTimeoutMillis = 300 * 1000;
	// 发生泄露时是否需要输出 log，建议在开启连接泄露检测时开启，方便排错
	private  boolean logAbandoned = false;
	// 只要maxPoolPreparedStatementPerConnectionSize>0,poolPreparedStatements就会被自动设定为true，使用oracle时可以设定此值。
	private  int maxPoolPreparedStatementPerConnectionSize = -1;


	public Connection getConnection() {
		try {
			conn = dataSource.getConnection();
		} catch (SQLException e) {
			logger.error("获取数据源的数据库连接失败", e);
			throw new RuntimeException(e);
		}
		return conn;
	}

	public void close() {
		dataSource.close();
	}
	
}
